//
// Created by liufenglin on 20-4-10.
//

#include "linkQueue.h"
#include <stdlib.h>
#include <stdio.h>


LinkQueue *newQueue(int cap) {
    LinkQueue *queue = calloc(1, sizeof(LinkQueue));
    queue->capacity = cap;
    queue->size = 0;
    pthread_mutex_init(&queue->lock, NULL);
    pthread_cond_init(&queue->notFullCond, NULL);
    pthread_cond_init(&queue->notEmptyCond, NULL);
    return queue;
}

void enQueue(LinkQueue *queue, char *str) {
    pthread_mutex_lock(&queue->lock);


    //
    while (queue->size == queue->capacity) {
//        printf("queue is full\n");
//        pthread_mutex_unlock(&queue->lock);
        pthread_cond_wait(&queue->notFullCond, &queue->lock);
//        return;
    }
    LinkNode *node = calloc(1, sizeof(LinkNode));
    node->data = str;

    if (queue->size == 0) {
        queue->head = node;
        queue->tail = node;
        queue->size++;
        pthread_mutex_unlock(&queue->lock);
        pthread_cond_broadcast(&queue->notEmptyCond);
        return;
    }
    if (queue->head == queue->tail) {
        queue->head->next = node;
    }
    queue->tail->next = node;
    queue->tail = node;
    queue->size++;
    pthread_mutex_unlock(&queue->lock);
    pthread_cond_broadcast(&queue->notEmptyCond);


}

//从队列头部取数据
char *deQueue(LinkQueue *queue) {
    pthread_mutex_lock(&queue->lock);
    //
    while (queue->size == 0) {
//        printf("queue is empty\n");
//        pthread_mutex_unlock(&queue->lock);
        pthread_cond_wait(&queue->notEmptyCond, &queue->lock);


//        return NULL;
    }
    LinkNode *head = queue->head;
    if (queue->size == 1) {

//        LinkNode *head = queue->head;
//        char *data = head->data;

//        queue->head = NULL;
        queue->tail = NULL;
//        free(head);
//        queue->size--;
//        return data;
    }

    char *data = head->data;
    queue->head = head->next;
    free(head);
    queue->size--;
    pthread_mutex_unlock(&queue->lock);
    pthread_cond_broadcast(&queue->notFullCond);
    return data;

}

void freeQueue(LinkQueue *queue) {
    if (queue != NULL) {
        pthread_mutex_destroy(&queue->lock);
        pthread_cond_destroy(&queue->notFullCond);
        pthread_cond_destroy(&queue->notEmptyCond);
        free(queue);
    }

}

